package org.gdstash.db;

import org.gdstash.util.GDMsgFormatter;
import org.gdstash.util.GDMsgLogger;

import java.sql.*;
import java.util.LinkedList;
import java.util.List;

public class DBLootTableSetAlloc {
    private static final String TABLE_NAME = "GD_LOOTTABLESET_ALLOC";
    private static final int ROW_TABLESET_ID = 1;
    private static final int ROW_LEVEL_MIN = 2;
    private static final int ROW_TABLE_ID = 3;
    private int levelMin;
    private String tableID;

    public DBLootTableSetAlloc() {
        this.levelMin = -1;
        this.tableID = null;
    }

    public int getMinLevel() {
        return this.levelMin;
    }

    public void setMinLevel(final int levelMin) {
        this.levelMin = levelMin;
    }

    public static boolean contains(final List<DBLootTableSetAlloc> list, final String tableID) {
        if (list == null) {
            return false;
        }
        if (tableID == null) {
            return false;
        }
        for (final DBLootTableSetAlloc alloc : list) {
            if (alloc.tableID.equals(tableID)) {
                return true;
            }
        }
        return false;
    }

    public String getTableID() {
        return this.tableID;
    }

    public void setTableID(final String tableID) {
        this.tableID = tableID;
    }

    public static void createTable() throws SQLException {
        final String dropTable = "DROP TABLE GD_LOOTTABLESET_ALLOC";
        final String createTable = "CREATE TABLE GD_LOOTTABLESET_ALLOC (TABLESET_ID VARCHAR(256) NOT NULL, LEVEL_MIN   INTEGER, TABLE_ID    VARCHAR(256) NOT NULL, PRIMARY KEY (TABLESET_ID, LEVEL_MIN, TABLE_ID))";
        try (final Connection conn = GDDBData.getConnection()) {
            final boolean auto = conn.getAutoCommit();
            conn.setAutoCommit(false);
            try (final Statement st = conn.createStatement()) {
                if (GDDBUtil.tableExists(conn, "GD_LOOTTABLESET_ALLOC")) {
                    st.execute(dropTable);
                }
                st.execute(createTable);
                st.close();
                conn.commit();
            } catch (SQLException ex) {
                conn.rollback();
                final Object[] args = {"GD_LOOTTABLESET_ALLOC"};
                final String msg = GDMsgFormatter.format(GDMsgFormatter.rbMsg, "ERR_CREATE_TABLE", args);
                GDMsgLogger.addError(msg);
                throw ex;
            } finally {
                conn.setAutoCommit(auto);
            }
        }
    }

    public static void delete(final Connection conn, final String tableSetID) throws SQLException {
        final String deleteEntry = "DELETE FROM GD_LOOTTABLESET_ALLOC WHERE TABLESET_ID = ?";
        try (final PreparedStatement ps = conn.prepareStatement(deleteEntry)) {
            ps.setString(1, tableSetID);
            ps.executeUpdate();
            ps.close();
        } catch (SQLException ex) {
            throw ex;
        }
    }

    public static void insert(final Connection conn, final DBLootTableSet dbTableSet) throws SQLException {
        if (dbTableSet.getAllocList() == null) {
            return;
        }
        if (dbTableSet.getAllocList().isEmpty()) {
            return;
        }
        final String insert = "INSERT INTO GD_LOOTTABLESET_ALLOC VALUES (?,?,?)";
        try (final PreparedStatement ps = conn.prepareStatement(insert)) {
            for (final DBLootTableSetAlloc entry : dbTableSet.getAllocList()) {
                if (entry.tableID != null) {
                    ps.setString(1, dbTableSet.getTableSetID());
                    ps.setInt(2, entry.levelMin);
                    ps.setString(3, entry.tableID);
                    ps.executeUpdate();
                    ps.clearParameters();
                }
            }
            ps.close();
            conn.commit();
        } catch (SQLException ex) {
            throw ex;
        }
    }

    public static List<DBLootTableSetAlloc> getByTableSetID(final String tableSetID) {
        List<DBLootTableSetAlloc> list = null;
        final String command = "SELECT * FROM GD_LOOTTABLESET_ALLOC WHERE TABLESET_ID = ?";
        try (final Connection conn = GDDBData.getConnection();
             final PreparedStatement ps = conn.prepareStatement(command)) {
            ps.setString(1, tableSetID);
            try (final ResultSet rs = ps.executeQuery()) {
                list = wrap(rs);
                conn.commit();
            } catch (SQLException ex) {
                throw ex;
            }
        } catch (SQLException ex2) {
            final Object[] args = {tableSetID, "GD_LOOTTABLESET_ALLOC"};
            final String msg = GDMsgFormatter.format(GDMsgFormatter.rbMsg, "ERR_READ_TABLE_BY_ID", args);
            GDMsgLogger.addError(msg);
            GDMsgLogger.addError(ex2);
        }
        return list;
    }

    private static List<DBLootTableSetAlloc> wrap(final ResultSet rs) throws SQLException {
        final LinkedList<DBLootTableSetAlloc> list = new LinkedList<DBLootTableSetAlloc>();
        while (rs.next()) {
            final DBLootTableSetAlloc entry = new DBLootTableSetAlloc();
            entry.levelMin = rs.getInt(2);
            entry.tableID = rs.getString(3);
            list.add(entry);
        }
        return list;
    }
}
